package org.cloud.core.common.anno.impl;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.cloud.core.common.anno.PrintLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @author Violet
 * @description 打印日志切面
 * @date 2021/5/22
 */
@Aspect
@Component
public class PrintLogAspect {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(org.cloud.core.common.anno.PrintLog)")
    public void pointCut() {
    }

    @AfterReturning(value = "pointCut()", returning = "result")
    public void printLog(JoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Class<? extends MethodSignature> signatureClass = signature.getClass();
        PrintLog annotation = method.getAnnotation(PrintLog.class);

        if (null != annotation) {
            String operaModule = annotation.operaModule();
            PrintLog.OperaType operaType = annotation.operaType();
            String operaDesc = annotation.operaDesc();
            boolean printParams = annotation.printParams();
            boolean printReturn = annotation.printReturn();

            StringBuilder sb = new StringBuilder();
            sb.append("执行模块:").append(operaModule);
            sb.append("执行方法:").append(signatureClass.getName()).append(method.getName());
            sb.append("方法类型:").append(operaType);
            sb.append("描述信息:").append(operaDesc);

            if (printParams) {
                sb.append("方法入参:");
                Parameter[] parameters = method.getParameters();
                for (Parameter p : parameters) {
                    //参数值(参数类型)
                    sb.append(p);
                    sb.append("(").append(p.getType()).append(")").append("\t");
                }
            }

            if (printReturn) {
                sb.append("方法返回值:").append(result);
            }

            log.info(sb.toString());
        }
    }
}
